package com.io.util;

import java.math.BigDecimal;

/**
 * @Title MathUtil.java
 * @Package com.mabang.util
 * @Description 提供精准的加减乘除算法
 * @author yangyx
 * @date 2016年5月21日 下午2:27:18
 */
public class MathUtil {
	// 默认除法运算精度 
	private static final int DEF_DIV_SCALE = 4; 
	// 这个类不能实例化 
	public MathUtil(){
	}
	
	public static BigDecimal add(BigDecimal v1,BigDecimal v2){
		if(v1==null && v2==null)
			return null;
		if(v1==null && v2!=null)
			return v2;
		if(v1!=null && v2==null)
			return v1;
		return v1.add(v2);
	}
	/** 
	* 提供精确的加法运算。 
	* 
	* @param v1 被加数 
	* @param v2 加数 
	* @return 两个参数的和 
	*/ 
	public static double add(double v1, double v2) { 
	   BigDecimal b1 = new BigDecimal(Double.toString(v1)); 
	   BigDecimal b2 = new BigDecimal(Double.toString(v2)); 
	   return b1.add(b2).doubleValue(); 
	} 
	/** 
	* 提供精确的减法运算。 
	* 
	* @param v1 被减数 
	* @param v2 减数 
	* @return 两个参数的差 
	*/ 
	public static double sub(double v1, double v2) { 
	   BigDecimal b1 = new BigDecimal(Double.toString(v1)); 
	   BigDecimal b2 = new BigDecimal(Double.toString(v2)); 
	   return b1.subtract(b2).doubleValue(); 
	} 
	/** 
	* 提供精确的乘法运算。 
	* 
	* @param v1 被乘数 
	* @param v2 乘数 
	* @return 两个参数的积 
	*/ 
	public static double mul(double v1, double v2) { 
	   BigDecimal b1 = new BigDecimal(Double.toString(v1)); 
	   BigDecimal b2 = new BigDecimal(Double.toString(v2)); 
	   return b1.multiply(b2).doubleValue(); 
	} 
	/** 
	* 提供（相对）精确的除法运算，当发生除不尽的情况时， 
	* 精确到小数点以后10位，以后的数字四舍五入。 
	* 
	* @param v1 被除数 
	* @param v2 除数 
	* @return 两个参数的商 
	*/ 
	public static double div(double v1, double v2) { 
	   return div(v1, v2, DEF_DIV_SCALE); 
	} 
	/** 
	* 提供（相对）精确的除法运算。 
	* 当发生除不尽的情况时，由scale参数指定精度，以后的数字四舍五入。 
	* 
	* @param v1 被除数 
	* @param v2 除数 
	* @param scale 表示表示需要精确到小数点以后几位。 
	* @return 两个参数的商 
	*/ 
	public static double div(double v1, double v2, int scale) { 
	   if (scale < 0) { 
	    throw new IllegalArgumentException("The scale must be a positive integer or zero"); 
	   } 
	   BigDecimal b1 = new BigDecimal(Double.toString(v1)); 
	   BigDecimal b2 = new BigDecimal(Double.toString(v2)); 
	   return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); 
	} 
	/** 
	* 提供精确的小数位四舍五入处理。 
	* 
	* @param v 需要四舍五入的数字 
	* @param scale 小数点后保留几位 
	* @return 四舍五入后的结果 
	*/ 
	public static double round(double v, int scale) { 
	   if (scale < 0) { 
	    throw new IllegalArgumentException("The scale must be a positive integer or zero"); 
	   } 
	   BigDecimal b = new BigDecimal(Double.toString(v)); 
	   BigDecimal one = new BigDecimal("1"); 
	   return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); 
	} 
	
	/**
	 * 提供两个double型的比较;-1, 0, or 1 as v1 is numerically less than, equal to, or greater than v2.
	 * @param v1 被比较数
	 * @param v2 比较数
	 * @return 比较结果
	 */
	public static int compare(double v1 , double v2){
		BigDecimal b1 = new BigDecimal(Double.toString(v1)); 
		BigDecimal b2 = new BigDecimal(Double.toString(v2)); 
		return b1.compareTo(b2);
	}
	public static int compare(BigDecimal v1 , BigDecimal v2){
		if(v1==null && v2==null)return 0;
		if(v1!=null && v2==null)return 1;
		if(v1==null && v2!=null)return -1;
		return v1.compareTo(v2);
	}
	public static BigDecimal sub(BigDecimal v1 , BigDecimal v2){
		if(v1== null) v1 = new BigDecimal("0");
		if(v2== null) v2 = new BigDecimal("0");
		return v1.subtract(v2);
	}
}
